#include "UserDatabase.h"

#include <QMessageBox>

UserDatabase::UserDatabase()
{
    initDatabase();
}

int UserDatabase::addUser(QString username, QString password, User::UserType type)
{
    int id = Database::FAILURE;

    open();

    QSqlQuery query;

    // Insert new user record
    query.prepare("INSERT INTO user_auth (username, password, type) "
                  "VALUES (:username, :password, :type)");
    query.bindValue(":username", QVariant(username));
    query.bindValue(":password", QVariant(password));
    query.bindValue(":type", type);
    query.exec();

    close();

    // Get generated user Id to return
    // NOTE: There is probably a more efficient way of doing this
    id = getId(username, password);

    return id;
}

int UserDatabase::getId(QString username, QString password)
{
    open();

    // Make query to find username and password in database
    QSqlQuery query;
    query.prepare("SELECT userId FROM user_auth "
               "WHERE username=:username "
               "AND password=:password");
    query.bindValue(":username", QVariant(username));
    query.bindValue(":password", QVariant(password));

    // Something went wrong with the SQL query (outdated database?)
    if (!query.exec())
    {
        QMessageBox::warning(NULL, "Warning", "Invalid SQL query.");
        return Database::FAILURE;
    }

    // If nothing was returned in the query, the username and password
    // combination does not exist in the database
    if (!query.next())
        return Database::FAILURE;

    // Read user id from query
    int idPos = query.record().indexOf("userId");
    int userId = query.value(idPos).toInt();

    close();
    return userId;
}

User::UserType UserDatabase::getType(int userId)
{
    open();

    // Make query to find user id in database
    QSqlQuery query;
    query.prepare("SELECT type FROM user_auth "
               "WHERE userId=:userId ");
    query.bindValue(":userId", QVariant(userId));

    // Something went wrong with the SQL query (outdated database?)
    if (!query.exec())
    {
        QMessageBox::warning(NULL, "Warning", "Invalid SQL query.");
        return User::INVALID;
    }

    // If nothing was returned in the query,
    // the user id was not found in the database
    if (!query.next())
        return User::INVALID;

    // Read user type from query
    int typePos = query.record().indexOf("type");
    User::UserType type = static_cast<User::UserType>(query.value(typePos).toInt());

    close();
    return type;
}

void UserDatabase::initDatabase()
{
    open();

    QSqlQuery query;

    // Check if user_auth table already exists
    query.exec("SELECT name FROM sqlite_master WHERE type='table' AND name = 'user_auth'");

    // If query returns a value, the table already exists and initialization can be skipped
    if (query.next())
    {
        close();
        return;
    }


    // Create table to hold user authentication data
    // Fields: userId, username, password, type
    query.exec("CREATE TABLE IF NOT EXISTS user_auth ("
               "userId INTEGER PRIMARY KEY AUTOINCREMENT, "
               "username varchar(255), "
               "password varchar(255), "
               "type int)");

    // Insert default admin with username "admin" and password "12345"
    query.exec("INSERT INTO user_auth (username, password, type)"
               "VALUES ('admin', '12345', 0)");

    close();
}

UserDatabase::~UserDatabase()
{
    close();
}
